View Javadoc

1   /*
2    * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted under the terms of either of the following
6    * Open Source licenses:
7    *
8    * The GNU General Public License, version 2, or any later version, as
9    * published by the Free Software Foundation
10   * (http://www.fsf.org/copyleft/gpl.html);
11   *
12   *  or
13   *
14   * The Semiotek Public License (http://webmacro.org/LICENSE.)
15   *
16   * This software is provided "as is", with NO WARRANTY, not even the
17   * implied warranties of fitness to purpose, or merchantability. You
18   * assume all risks and liabilities associated with its use.
19   *
20   * See www.webmacro.org for more information on the WebMacro project.
21   */
22  
23  
24  package org.webmacro.servlet;
25  
26  import org.webmacro.Broker;
27  import org.webmacro.InitException;
28  import org.webmacro.Log;
29  import org.webmacro.util.LogSystem;
30  
31  import javax.servlet.Servlet;
32  import javax.servlet.ServletContext;
33  import java.io.InputStream;
34  import java.net.URL;
35  import java.util.Properties;
36  
37  /***
38   * An implementation of Broker tailored for Servlet 2.0/2.1
39   * environments.
40   * <p>
41   * Loads templates and other resources from:
42   * <ol>
43   * <li> the class path,
44   * </p>
45   * writes log messages to the servlet log.
46   * @author Brian Goetz
47   * @author Marc Palmer (wj5@wangjammers.org)
48   * @since 0.96
49   */
50  
51  public class Servlet20Broker extends ServletBroker
52  {
53  
54      protected ClassLoader _servletClassLoader;
55  
56      protected Servlet20Broker (ServletContext sc,
57                               ClassLoader cl,
58                               Properties additionalProperties) throws InitException
59      {
60          super(sc);
61          _servletClassLoader = cl;
62  
63          String propertySource = WEBMACRO_DEFAULTS + ", " + WEBMACRO_PROPERTIES;
64          loadDefaultSettings();
65          loadSettings(WEBMACRO_PROPERTIES, true);
66          if (additionalProperties != null && additionalProperties.keySet().size() > 0)
67          {
68              propertySource += ", (additional Properties)";
69              loadSettings(additionalProperties);
70          }
71          propertySource += ", (System Properties)";
72          loadSystemSettings();
73          initLog(_config);
74  
75          _log.notice("Loaded settings from " + propertySource);
76          init();
77      }
78  
79      /***
80       * Get a Servlet API 2.0 compatible broker for the Servlet specified
81       * @param s The servlet
82       * @param additionalProperties
83       * @return The broker for the servlet context.
84       * @throws InitException
85       */
86      public static Broker getBroker (Servlet s, Properties additionalProperties) throws InitException
87      {
88          ServletContext sc = s.getServletConfig().getServletContext();
89          ClassLoader cl = s.getClass().getClassLoader();
90          return _getBroker(sc, cl, additionalProperties, true,
91                  s.getClass().getName());
92      }
93  
94      /***
95       * Get a Servlet API 2.0 compatible broker for the ServletContext specified
96       * @param sc The Servlet context
97       * @param cl A ClassLoader to use, presumably the webapp classloader
98       * @param additionalProperties
99       * @return The broker for the servlet context
100      * @throws InitException
101      * @since 2.1 JSDK
102      */
103     public static Broker getBroker (ServletContext sc, ClassLoader cl,
104         Properties additionalProperties) throws InitException
105     {
106         return _getBroker(sc, cl, additionalProperties, false, sc.toString() );
107     }
108 
109     /***
110      * Get an existing instance of the Servlet 2.0/2.1 broker or create a new one.
111      * Templates will be retrieved relative to the ServletContext root
112      * and classes loaded from the ClassLoader passed in. NOTE: Templates
113      * will <b>not</b> be loaded from the classpath.
114      * @param sc The ServletContext to template access
115      * @param cl The ClassLoader for class loading, typically servlet or
116      * JSP page's class loader
117      * @param additionalProperties
118      * @param fromServlet true if it is actually an initialization derived from
119      * a Servlet instance passed in - just for nicer logging output
120      * @param servletOrContextName Name of the servlet or context originating this broker,
121      * for nicer logging
122      * @return The broker for the servlet context
123      * @throws org.webmacro.InitException
124      * @since 2.1 JSDK
125      */
126     protected static Broker _getBroker (ServletContext sc,
127         ClassLoader cl, Properties additionalProperties, boolean fromServlet,
128         String servletOrContextName) throws InitException
129     {
130         try
131         {
132             Object key = cl;
133             if (additionalProperties != null && additionalProperties.keySet().size() > 0)
134                 key = new PropertiesPair(cl, additionalProperties);
135 
136             Broker b = findBroker(key);
137             if (b == null)
138             {
139                 b = new Servlet20Broker(sc, cl, additionalProperties);
140                 register(key, b);
141             }
142             else
143                 b.getLog("broker").notice(
144                     (fromServlet ? "Servlet " : "ServletContext ")
145                     + servletOrContextName
146                     + " joining Broker" + " " + b.getName() );
147             return b;
148         }
149         catch (InitException e)
150         {
151             Log log = LogSystem.getSystemLog("wm");
152             log.error("Failed to initialized WebMacro from "+
153                     (fromServlet ? "Servlet " : "ServletContext ")
154                     + servletOrContextName);
155             throw e;
156         }
157     }
158 
159     /***
160      * Get a resource (file) from the the Broker's class loader */
161     public URL getResource (String name)
162     {
163         URL u = _servletClassLoader.getResource(name);
164         if (u == null)
165             u = super.getResource(name);
166         return u;
167     }
168 
169     /***
170      * Get a resource (file) from the Broker's class loader
171      */
172     public InputStream getResourceAsStream (String name)
173     {
174         InputStream is = _servletClassLoader.getResourceAsStream(name);
175         if (is == null)
176             is = super.getResourceAsStream(name);
177         return is;
178     }
179 
180     /***
181      * Loads a class by name. Uses the servlet classloader to load the
182      * class. If the class is not found uses the Broker classForName
183      * implementation.  */
184 
185     public Class classForName (String name) throws ClassNotFoundException
186     {
187         Class cls = null;
188         try
189         {
190             cls = _servletClassLoader.loadClass(name);
191         }
192         catch (ClassNotFoundException e)
193         {
194         }
195 
196         if (cls == null)
197             cls = super.classForName(name);
198 
199         return cls;
200     }
201 
202 }